﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using FgoDataCrawler.Entity;
using FgoDataCrawler.Utility;
using HtmlAgilityPack;
using NLog;

namespace FgoDataCrawler.Crawler
{
    public class WikiaCrawler
    {
        private const string BASE_URL = "http://fategrandorder.wikia.com/wiki";
        private const string DEFAULT_CACHE_DIR = "D:\\temp\\Wikia";

        private static Logger logger = LogManager.GetCurrentClassLogger();
        // private HttpClient httpClient { get; set; }
        private CachedHttpClient chClient { get; set; }

        public WikiaCrawler()
        {
            chClient = new CachedHttpClient(DEFAULT_CACHE_DIR);
        }

        public IList<ServantInfo> CrawlServantList()
        {
            IList<ServantInfo> servants = new List<ServantInfo>();

            var url = BASE_URL + "/Servant_List";
            logger.Info("开始抓取{0}", url);
            DateTime startTime = DateTime.Now;
            var content = chClient.GetAsString("Servant_List.html", url, Encoding.UTF8);
            TimeSpan timeCost = DateTime.Now - startTime;
            logger.Info("抓取完成，耗时{0}ms", timeCost.Milliseconds);

            var doc = new HtmlDocument();
            logger.Info("开始解析页面");
            startTime = DateTime.Now;
            doc.LoadHtml(content);
            timeCost = DateTime.Now - startTime;
            logger.Info("页面解析完成，耗时{0}ms", timeCost.Milliseconds);

            var xpath = "//*[contains(@class,'tabbertab')]";
            var tabbertabs = doc.DocumentNode.SelectNodes(xpath);
            
            logger.Info("找到{0}个.tabbertab节点", tabbertabs.Count);

            foreach (var classTab in tabbertabs)
            {
                var className = classTab.GetAttributeValue("title", "");
                if (className == "") continue;
                
                logger.Info("分析{0}选项卡", className);
                var table = classTab.SelectSingleNode("./p/table");
                var trs = table.SelectNodes("./tr");
                logger.Info("表格中找到{0}组从者信息", trs.Count - 1);

                for (int index = 1; index < trs.Count; index++)
                {
                    ServantInfo servant = new ServantInfo();
                    try
                    {
                        var tr = trs[index];
                        var tds = tr.SelectNodes("./td");
                        if (tds.Count != 4)
                        {
                            logger.Warn("第{0}行的列数异常", index);
                            continue;
                        }

                        var tdIcon = tds[0];
                        var tdServantName = tds[1];
                        var tdStars = tds[2];
                        var tdId = tds[3];

                        if (tdId.InnerText.Trim() == "Null (Enemy-Only Version)") continue;

                        servant.Id = Int32.Parse(tdId.InnerText);
                        servant.EnglishName = tdServantName.InnerText.Trim();

                        servant.IsBoss = false;
                        xpath = "./span/a/img";
                        // Beast阶的Boss以及所罗门
                        if (className == "Beast" || servant.Id == 83 || servant.Id == 152)
                        {
                            xpath = "./a/img";
                            servant.IsBoss = true;
                        }
                        var img = tdIcon.SelectSingleNode(xpath);
                        var imgDataSrc = img.Attributes["data-src"].Value;
                        int revisionIndex = imgDataSrc.IndexOf("/revision");

                        servant.MainAvatar = imgDataSrc.Substring(0, revisionIndex);

                        if (!servant.IsBoss)
                        {
                            var hovertable = tdIcon.SelectSingleNode(".//table[contains(@style,'width:485px;text-align:left;')]");
                            var hoverTrs = hovertable.SelectNodes("./tr");
                            servant.JapaneseName = hoverTrs[1].InnerText.Trim();  // .Replace("?", "・");
                        }
                        
                        switch (className)
                        {
                            case "Saber":
                            case "Archer":
                            case "Lancer":
                            case "Rider":
                            case "Caster":
                            case "Assassin":
                            case "Berserker":
                                servant.Class = className;
                                break;
                            default:
                                servant.Class = "Extra";
                                break;
                        }

                        servants.Add(servant);
                    }
                    catch (Exception ex)
                    {
                        logger.Warn("第{0}行解析时出错！", index);
                        logger.Warn(ex.Message);
                    }
                }
            }

            return servants;
        }
    }
}
